#include "Rectangle2DHandler.h"
#include "CmdManager.h"
#include "SendPointHandlerBase.h"
#include "Scene.h"
#include "Ucs.h"
#include "LineStrip2D.h"
#include "qundostack.h"
#include "Operation/OpAdd.h"
#include "QtOSGWidget.h"

Rectangle2DHandler::Rectangle2DHandler()
{
}

Rectangle2DHandler::~Rectangle2DHandler()
{
}

bool isEqual(double x1, double x2)
{
	return std::abs(x1 - x2) < 0.001; // 1 mm
}

void Rectangle2DHandler::input(const QVariant& data, const QString& rawInput, CommandSource cs)
{
	auto sph = getSendPointHandler();
	auto scene = getScene();
	auto widget3D = getWidget();
	auto ucs = scene->getCurrentUCS();
	if (data.type() == QVariant::Bool && !data.toBool())
	{
		if (m_rectangle)
		{
			widget3D->pauseRenderThread();
			ucs->removeChild(m_rectangle);
			widget3D->resumeRenderThread();
		}
		emit finished();
		return;
	}

	if (status() == 0)
	{
		if (sph)
		{
			sph->setPointMask(CS_LBTNDOWN);
		}

		m_rectangle = std::make_shared<LineStrip2D>(ucs.get());
		m_rectangle->setColor(ucs->getUCSColor());
		widget3D->pauseRenderThread();
		ucs->addChild(m_rectangle);
		widget3D->resumeRenderThread();
		prompt(1, tr("指定第一个角点:"));
		return;
	}

	std::vector<osg::Vec3d> points = m_rectangle->getPoints();
	if (status() == 1)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			widget3D->pauseRenderThread();
			ucs->removeChild(m_rectangle);
			widget3D->resumeRenderThread();
			emit finished();
			return;
		}
		if (sph)
		{
			sph->setPointMask(CS_LBTNDOWN | CS_MOUSEMOVE);
		}
		osg::Vec3d ucspt;
		if (getPoint2D(*ucs, data, rawInput, cs, ucspt))
		{
			for (int i = 0; i < 5; i++)
			{
				points.push_back(osg::Vec3d(ucspt.x(), ucspt.y(), 0));
			}
			m_rectangle->setPoints(points);
			prompt(2, tr("指定相对的角点:"));
		}
		return;
	}

	if (status() == 2)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			// 只有一个点，不能形成矩形
			widget3D->pauseRenderThread();
			ucs->removeChild(m_rectangle);
			widget3D->resumeRenderThread();
			emit finished();
			return;
		}
		osg::Vec3d ucspt;
		if (getPoint2D(*ucs, data, rawInput, cs, ucspt))
		{
			points[1] = osg::Vec3d(ucspt.x(), points[0].y(), 0);
			points[2] = osg::Vec3d(ucspt.x(), ucspt.y(), 0);
			points[3] = osg::Vec3d(points[0].x(), ucspt.y(), 0);
			points[4] = points[0];
			if (cs == CS_MOUSEMOVE)
			{
				m_rectangle->setPoints(points);
			}
			else
			{
				if (isEqual(points[0].x(), ucspt.x()) || isEqual(points[0].y(), ucspt.y()))
				{
					//两点共线
					widget3D->pauseRenderThread();
					ucs->removeChild(m_rectangle);
					widget3D->resumeRenderThread();
					emit finished();
					return;
				}
				m_rectangle->setPoints(points);
				auto undoStack = scene->undoStack();
				std::set<std::shared_ptr<INode>> children;
				children.insert(m_rectangle);
				undoStack->push(new OpAdd(children));
				emit finished();
				return;
			}
		}
	}
}